# Redux - 01

React只是一个轻量级的视图框架,并没有很好的去解决复杂组件的通信,交互等问题,Redux解决了这个问题 新版本 - reduxjs/toolkit (opens new window)

类似Vux

# Redux工作流

主体:

- ReactComponent (借阅者)
- Action Creators (图书管理员)
- Store (图书馆)
- Reducer (管理软件)

流程:

ReactComponent -> Action Creators -> Store <-> Reducer

Store -> ReactComponent

解释:

我需要借书 -> 图书馆管理员 -> 进入图书馆 -> 查询图书管理软件

管理软件告知结果 -> 图书馆 -> 借阅

# 实战

思考:啥时候往redux里面写,多个reduces怎么弄?命名空间?

# 创建store

新建store文件夹,其下创建index.js,reduceer.js


//index.js

import {createStore} from 'redux'
import reducer from './reducer'
const store = createStore(reducer)
export default store

// reducer.js

const defaultState = {}
const reducer = (state = defaultState, action) => {
     return state
})
export default reducer

reducer 中不能直接操作state

# TODOLIST

和之前写的demo一样,简单的增删改查,只不过将其state放入store中进行操作。

# 获取store中的state


store.getState()

# Action

和vux一样,state的改变需要通过提交action来进行操作, 已同步input.value来举例

function changeInput (e) {
    const action = {
        type: 'changeInput',
        value: e.target.value
    }
    store.dispatch(action)
}
// reducer.js
const defaultState = {
  inputValue: '',
  list: [
    'asfasfasf',
    'asf1213123',
    '阿瑟费大方'
  ]
}
const reducer = (state = defaultState, action) => {
    if (action.type === 'changeInput') {
        state.list.push(action.value)
    }
    return state
})

这里会报一个错,因为action不可直接对state进行修改

所以

const reducer = (state = defaultState, action) => {
    if (action.type === 'changeInput') {
        let newState = _.deepCopy(state)
        newState.list.push(action.value)
        return newState
    }
    return state
})

这样就完成了对input输入的监听。

注意:如果input进行了value的绑定,则无法触发视图的更新

<Input
    value={this.state.inputValue}
    onChange={(e) => this.change(e)}
/>

我们还需要设置订阅来进行视图更新

store.subscribe(() =>  {this.setState(store.getState())})

但如果没有进行value的绑定,则无需订阅。

# 复用性增加

action 的命名现在看起来蠢的要死,不知道后期会有什么好办法。暂时可以将action.type进行集中管理,万一以后用到呢。书中可能会有好答案。

新建actionTypes.js

exprot const CHANGE_INPUT = 'changeInput'

用的时候引入替换掉即可。